package com.taijihuabao.common.commonutils;

import com.taijihuabao.modules.entity.UserEntity;
import io.jsonwebtoken.*;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 工具类
 *
 * @author changhui.tu
 */
public class JwtTokenUtil {

    /**
     * 默认缓存时间 10分钟
     */
    public final static int TEN_MINUTE = 60 * 60 * 24 * 7;

    /**
     * 常量部分:token过期时间,秘钥
     */
    public static final long EXPIRE = TEN_MINUTE * 30 * 60;
    public static final String SECRET = "HFedr5gE55DFD5reh5dfg451drgdr";

    /**
     * 生成Token字符串
     *
     * @param userEntity
     * @return
     */
    public static String createToken(UserEntity userEntity) {
        String token = Jwts.builder()

                //头部:  设置头部typ属性表示令牌的类型，JWT令牌统一写为JWT。
                //alg属性表示签名使用的算法，默认为HMAC SHA256（写为HS256）
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")

                //载荷:主题,签发日期,设置过期时间
                .setSubject("user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))

                //自定义私有字段:设置token主体部分，存储用户信息。 注意:未加密，所有人可解读不要存放重要信息
                .claim("id", userEntity.getId())
                .claim("name", userEntity.getName())
                .claim("sex", userEntity.getSex())

                //签证:加密策略
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();

        return token;
    }

    /**
     * 解析Token:缓存中，token是否过期
     *
     * @param token
     * @return
     */
    public static boolean isExpiration(String token) {
        //判断传过来的token是否为null，为null直接返回false
        if (StringUtils.isEmpty(token)) {
            return false;
        }
        try {
            //通过秘钥解密token
            Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
        } catch (Exception e) {
            //解密失败，抛出异常
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 解析Token:客户端，token是否过期
     *
     * @param request
     * @return
     */
    public static boolean isExpiration(HttpServletRequest request) {
        try {
            String token = request.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                return false;
            }
            //通过秘钥解密token
            Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
        } catch (Exception e) {
            //解密失败，抛出异常
            e.printStackTrace();
            return false;
        }
        return true;

    }

    /**
     * 获取token里的用户信息
     *
     * @param request
     * @return
     */
    public static Map<String, Object> tokenInfo(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        //使用jjwt的parseClaimsJwt(String jwt)方法验证签名的token时候
        //会抛 Signed Claims JWSs are not supported 异常，签名的token应该使用parseClaimsJws(String jws) 方法，生成与验证类型对应
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
        Claims body = claimsJws.getBody();
        Map<String, Object> map = new HashMap<>(10);
        map.put("id", body.get("id"));
        map.put("name", body.get("name"));
        map.put("sex", body.get("sex"));
        return map;
    }

}
